package com.nbsaas.boot;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.nbsaas.boot.api.adapter.RegistryAdapter;
import com.nbsaas.boot.api.adapter.ServiceInstance;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Nacos注册中心适配器实现
 * 
 * @author nbsaas
 */
public class NacosRegistryAdapter implements RegistryAdapter {
    
    private NamingService namingService;
    private String serverAddr;
    private String namespace;
    private String group;
    
    /**
     * 默认构造函数，使用默认配置
     */
    public NacosRegistryAdapter() {
        this("127.0.0.1:8848", "public", "DEFAULT_GROUP");
    }
    
    /**
     * 构造函数
     * 
     * @param serverAddr nacos服务器地址
     * @param namespace 命名空间
     * @param group 分组
     */
    public NacosRegistryAdapter(String serverAddr, String namespace, String group) {
        this.serverAddr = serverAddr;
        this.namespace = namespace;
        this.group = group;
        
        try {
            Properties properties = new Properties();
            properties.put("serverAddr", serverAddr);
            properties.put("namespace", namespace);
            
            this.namingService = NamingFactory.createNamingService(properties);
        } catch (NacosException e) {
            throw new RuntimeException("Failed to create Nacos naming service", e);
        }
    }
    
    @Override
    public void register(ServiceInstance instance) {
        try {
            Instance nacosInstance = convertToNacosInstance(instance);
            
            String serviceName = instance.getName();
            String groupName = getGroup(instance);
            
            namingService.registerInstance(serviceName, groupName, nacosInstance);
            
        } catch (NacosException e) {
            throw new RuntimeException("Failed to register service instance to Nacos", e);
        }
    }

    @Override
    public void deregister(ServiceInstance instance) {
        try {
            String serviceName = instance.getName();
            String groupName = getGroup(instance);
            String host = instance.getHost();
            Integer port = instance.getPort();
            
            if (host != null && port != null) {
                namingService.deregisterInstance(serviceName, groupName, host, port);
            }
            
        } catch (NacosException e) {
            throw new RuntimeException("Failed to deregister service instance from Nacos", e);
        }
    }

    @Override
    public void updateStatus(ServiceInstance instance, String status) {
        try {
            String serviceName = instance.getName();
            String groupName = getGroup(instance);
            String host = instance.getHost();
            Integer port = instance.getPort();
            
            if (host != null && port != null) {
                // 根据状态进行重新注册或注销
                if ("DOWN".equalsIgnoreCase(status)) {
                    deregister(instance);
                } else if ("UP".equalsIgnoreCase(status)) {
                    // 创建新的实例并注册
                    Instance nacosInstance = convertToNacosInstance(instance);
                    namingService.registerInstance(serviceName, groupName, nacosInstance);
                }
            }
            
        } catch (NacosException e) {
            throw new RuntimeException("Failed to update service instance status in Nacos", e);
        }
    }
    
    /**
     * 将ServiceInstance转换为Nacos Instance
     */
    private Instance convertToNacosInstance(ServiceInstance serviceInstance) {
        Instance instance = new Instance();
        
        // 基本信息
        instance.setIp(serviceInstance.getHost());
        instance.setPort(serviceInstance.getPort() != null ? serviceInstance.getPort() : 8080);
        
        // 健康状态
        instance.setHealthy(!"DOWN".equalsIgnoreCase(serviceInstance.getStatus()));
        instance.setEnabled(!"DOWN".equalsIgnoreCase(serviceInstance.getStatus()));
        
        // 设置元数据
        Map<String, String> metadata = new HashMap<>();
        if (serviceInstance.getMetadata() != null) {
            metadata.putAll(serviceInstance.getMetadata());
        }
        
        // 添加协议信息
        if (serviceInstance.getProtocol() != null) {
            metadata.put("protocol", serviceInstance.getProtocol());
        }
        
        // 添加地址信息
        if (serviceInstance.getAddress() != null) {
            metadata.put("address", serviceInstance.getAddress());
        }
        
        // 添加健康检查URL
        if (serviceInstance.getHealthCheckUrl() != null) {
            metadata.put("healthCheckUrl", serviceInstance.getHealthCheckUrl());
        }
        
        // 添加标签信息
        if (serviceInstance.getTags() != null && !serviceInstance.getTags().isEmpty()) {
            metadata.put("tags", String.join(",", serviceInstance.getTags()));
        }
        
        instance.setMetadata(metadata);
        
        // 设置权重（如果在元数据中指定）
        if (serviceInstance.getMetadata() != null && serviceInstance.getMetadata().containsKey("weight")) {
            try {
                double weight = Double.parseDouble(serviceInstance.getMetadata().get("weight"));
                instance.setWeight(weight);
            } catch (NumberFormatException e) {
                // 使用默认权重1.0
                instance.setWeight(1.0);
            }
        } else {
            instance.setWeight(1.0);
        }
        
        return instance;
    }
    
    /**
     * 获取服务分组，优先从实例元数据中获取，否则使用默认分组
     */
    private String getGroup(ServiceInstance instance) {
        if (instance.getMetadata() != null && instance.getMetadata().containsKey("group")) {
            return instance.getMetadata().get("group");
        }
        return this.group;
    }
    
    /**
     * 关闭Nacos客户端连接
     */
    public void close() {
        if (namingService != null) {
            try {
                namingService.shutDown();
            } catch (NacosException e) {
                // 忽略关闭异常
            }
        }
    }
} 